﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Core.Entities
{
    /// <summary>
    /// 函数参数签名标识
    /// </summary>
    public sealed class MethodSign
    {
        /// <summary>
        /// 构造函数参数签名标识
        /// </summary>
        /// <param name="Name">函数的名称</param>
        /// <param name="ParamsTypes">函数的参数类型</param>
        /// <param name="ResultType">函数的返回值类型</param>
        public MethodSign(string Name, Type[] ParamsTypes, Type ResultType)
        {
            this.Name = Name;
            this.ParamsTypes = ParamsTypes;
            this.ResultType = ResultType;

            // 计算 HashCode。
            int TempHashCode = Name.GetHashCode();

            foreach (var Item in ParamsTypes)
            {
                TempHashCode ^= Item.GetHashCode();
            }

            TempHashCode ^= ResultType.GetHashCode();

            HashCode = TempHashCode;
        }

        public readonly string Name;
        public readonly Type[] ParamsTypes;
        public readonly Type ResultType;
        private readonly int HashCode;


        public override int GetHashCode()
        {
            return HashCode;
        }

        public override bool Equals(object obj)
        {
            return obj is MethodSign && this == (MethodSign)obj;
        }

        /// <summary>
        /// 比较两个 MethodSign 是否相同。
        /// </summary>
        /// <param name="XSign">第一个 MethodSign。</param>
        /// <param name="YSign">第二个 MethodSign。</param>
        /// <returns>两个 MethodSign 是否相同。</returns>
        public static bool operator ==(MethodSign XSign, MethodSign YSign)
        {
            if (XSign.HashCode == YSign.HashCode && XSign.Name == YSign.Name && XSign.ParamsTypes.Length == YSign.ParamsTypes.Length && XSign.ResultType == YSign.ResultType)
            {
                for (int i = 0; i < XSign.ParamsTypes.Length; i++)
                {
                    if (XSign.ParamsTypes[i] != YSign.ParamsTypes[i])
                    {
                        return false;
                    }
                }

                return true;
            }

            return false;
        }

        /// <summary>
        /// 比较两个 MethodSign 是否不相同。
        /// </summary>
        /// <param name="XSign">第一个 MethodSign。</param>
        /// <param name="YSign">第二个 MethodSign。</param>
        /// <returns>两个 MethodSign 是否不相同。</returns>
        public static bool operator !=(MethodSign XSign, MethodSign YSign)
        {
            return !(XSign == YSign);
        }
    }
}